#!/usr/bin/env python
# -*- python-mode -*-

import sys, os, time

NfsEventCounters = [
    'inoderevalidates',
    'dentryrevalidates',
    'datainvalidates',
    'attrinvalidates',
    'vfsopen',
    'vfslookup',
    'vfspermission',
    'vfsupdatepage',
    'vfsreadpage',
    'vfsreadpages',
    'vfswritepage',
    'vfswritepages',
    'vfsreaddir',
    'vfssetattr',
    'vfsflush',
    'vfsfsync',
    'vfslock',
    'vfsrelease',
    'congestionwait',
    'setattrtrunc',
    'extendwrite',
    'sillyrenames',
    'shortreads',
    'shortwrites',
    'delay'
]

NfsByteCounters = [
    'normalreadbytes',
    'normalwritebytes',
    'directreadbytes',
    'directwritebytes',
    'serverreadbytes',
    'serverwritebytes',
    'readpagescount',
    'writepagescount'
]

NfsTimeCounters = [
    'filewrite',
    'preparewrite',
    'nfsupdatepage',    
    'fileread',
    'fileflush',
    'readpage',
    'readpages',
    'writepage',
    'writepages',
    'congestionwait'
]

class DeviceData:
    def __init__(self):
	self.__nfs_data = dict()
        self.__rpc_data = dict()
	self.__rpc_data['ops'] = []
	self.fcount = 0		 

    def parse_nfs_line(self, words):
        if words[0] == 'events:':
	    i = 1
	    for key in NfsEventCounters:
		if self.fcount <= 1:
	            self.__nfs_data[key] = int(words[i])
		else:
		    self.__nfs_data[key] += int(words[i])		    
		i += 1
	elif words[0] == 'bytes:':
	    i = 1
	    for key in NfsByteCounters:
		if self.fcount <= 1:
	            self.__nfs_data[key] = int(words[i])
		else:
		    self.__nfs_data[key] += int(words[i])		    
		i += 1
	elif words[0] == 'time:':	  
            i = 1
	    for key in NfsTimeCounters:
		if self.fcount <= 1:
	            self.__nfs_data[key] = int(words[i])
		else:
		    self.__nfs_data[key] += int(words[i])		    
		i += 1
 
    def parse_rpc_line(self, words):
	if words[0] == 'RPC':
		i = 0
	elif words[0] == 'xprt:':
		i = 0
	elif words[0] == 'per-op':
		i = 0
	else:
	     """remove last comma"""
	     op = words[0][:-1]
	     if self.fcount <=1 :	
	     	 self.__rpc_data['ops'] += [op]
	         self.__rpc_data[op] = [long(word) for word in words[1:]]
	     else:
		  for i in range(len(self.__rpc_data[op])):
		      self.__rpc_data[op][i] += long(words[i+1])
	   
    def parse_file(self, fname):
        fd=file(fname)
	found = 0
        for line in fd.readlines():
	    words = line.split()
    	    if len(words) == 0:
	        continue
	    if(not found and words[0] != 'RPC'):
    	        self.parse_nfs_line(words)
	 	continue
	    found = 1
     	    self.parse_rpc_line(words)

    def print_rpc_info(self, op, num):
	if not self.__rpc_data.has_key(op):
		return
	
	rpc_data = self.__rpc_data[op]
	ops = float(rpc_data[0]) / num
	bytes = float(rpc_data[3] + rpc_data[4]) / num
	bytes /= 1024
	time = float(rpc_data[7]) / num
	
	if ops != 0:
	    avgtime = time / ops
	else:
	    avgtime = 0

	print '%s' %op.lower().ljust(10),
	print '\t%7.3f' % ops,
	print '\t%7.3f' % time,
	print '\t%7.3f' % bytes,
	print '\t%7.3f' % avgtime

    def print_stats(self, num):
	print '--------nfs events--------'
	for key in NfsEventCounters:
	    print '%18s\t%d' %(key, self.__nfs_data[key]/num)
	
	print '-------nfs bytes----------'
	for key in NfsByteCounters:
	    if key in  ['readpagescount', 'writepagescount']:
	        print '%18s\t %d' %(key,  self.__nfs_data[key] * 4 / num)
		continue
	    print '%18s\t %d' %(key, self.__nfs_data[key] / 1024 / num)
	
 	print '\t\t #ops\t\t total time(ms)\t KB\t\t avg time(ms)'
	for op in self.__rpc_data['ops']:
	    self.print_rpc_info(op, num)

def iostat_command():
    filelist = sys.argv
    if len(sys.argv) < 2:
	filelist += ['/proc/self/mountstats']

    print 'file NO %d' %(len(filelist) - 1)
    stats = DeviceData()
    for fname in filelist[1:]:
	stats.fcount += 1
	stats.parse_file(fname)
    stats.print_stats(len(filelist) - 1)
	
iostat_command()








